#include "StdAfx.h"
#include "WPModel.h"
#include "TextUtility.h"
#include "WPContext.h"


CWPModel::CWPModel(void)
: m_pViewModel(NULL)
  ,m_nTrainMode(E_TYPE_TRAIN_PREVIEW)
  ,m_nReviewMode(0)
  ,m_ptSR(NULL)
{
}

CWPModel::CWPModel(UINT nTrainMode, IWPViewModel* pWnd)
: m_pViewModel(pWnd)
  ,m_nTrainMode(nTrainMode)
  ,m_nReviewMode(0)
  ,m_ptSR(NULL)
{
}

CWPModel::~CWPModel(void)
{

}

BOOL CWPModel::Load()
{
    if (m_db.Open("nyedu.db")) {
        GetAllLevelItem();
        return TRUE;
    }
    return FALSE;
}

void CWPModel::GetAllLevelItem()
{
    m_vectLevel.clear();
    SQLiteStatement* stmt = m_db.Statement("select * from nyxm_study_section where nid=0 order by sort");
    if (stmt != NULL)
    {
        while (stmt->NextRow()) {
            TLevelItem li;
            li.nId = stmt->ValueInt(3);
            CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), li.szName, sizeof(li.szName));
            m_vectLevel.push_back(li);
        } 
    }
}

void CWPModel::GetMaterialsByLevel(LPCTSTR lpszLevelName)
{
    int nId = 0;
    for (int i = 0; i < m_vectLevel.size(); ++i)
    {
        if (0 == _tcscmp(m_vectLevel[i].szName, lpszLevelName))
        {
            nId = m_vectLevel[i].nId;
            break;
        } 
    }

    char szSQL[1024] = {0};
    sprintf(szSQL, "select * from nyxm_version where nid=%d order by sort", nId);
    if (nId != 0)
    {
        TCHAR szName[512] = {0};
        SQLiteStatement* stmt = m_db.Statement(szSQL);
        while (stmt->NextRow()) {
            CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), szName, sizeof(szName));
            int nId = stmt->ValueInt(0);
            CDuiString sText;
            sText.SmallFormat(_T("%d_%s"), nId, szName);
            if (m_pViewModel != NULL)
            {
                m_pViewModel->UpdateMaterialsView(sText);
            }
        }
    }
}

void CWPModel::GetGradesByMaterial(LPCTSTR lpszMaterial)
{
    CDuiString sText = lpszMaterial;
    int nPos = sText.Find(_T("_"));
    char szSQL[1024] = {0};
    char szID[8] = {0};
    CTextUtility::UnicodeToMB(sText.Left(nPos).GetData(), szID, sizeof(szID));
    sprintf(szSQL, "select * from nyxm_semester where vid=%s order by sort", szID);
    SQLiteStatement* stmt = m_db.Statement(szSQL);
    TCHAR szName[512] = {0};
    while (stmt->NextRow()) {
        CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), szName, sizeof(szName));
        int nId = stmt->ValueInt(0);
        CDuiString sText;
        sText.SmallFormat(_T("%d_%s"), nId, szName);
        if (m_pViewModel != NULL)
        {
            m_pViewModel->UpdateGradesView(sText);
        }
    }
}

void CWPModel::GetUnitsByGrade(LPCTSTR lpszGrade)
{
    CDuiString sText = lpszGrade;
    int nPos = sText.Find(_T("_"));
    char szSQL[1024] = {0};
    char szID[8] = {0};
    CTextUtility::UnicodeToMB(sText.Left(nPos).GetData(), szID, sizeof(szID));
    sprintf(szSQL, "select * from nyxm_unit where sid=%s order by sort", szID);
    SQLiteStatement* stmt = m_db.Statement(szSQL);
    TCHAR szName[512] = {0};
    while (stmt->NextRow()) {
        CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), szName, sizeof(szName));
        int nId = stmt->ValueInt(0);
        CDuiString sText;
        sText.SmallFormat(_T("%d_%s"), nId, szName);
        if (m_pViewModel != NULL)
        {
            m_pViewModel->UpdateUnitsView(sText);
        }
    }
}

int CWPModel::UpdateUnitWords(std::vector<TUnitWord>& vectWords)
{
    m_vectWords.clear();

    for (int i = 0; i < vectWords.size(); ++i)
    {
        m_vectWords.push_back(vectWords[i]);
    }

    return m_vectWords.size();
}

int CWPModel::GetWordsByUnit(LPCTSTR lpUnit)
{
    m_vectWords.clear();

    CDuiString sText = lpUnit;
    int nPos = sText.Find(_T("_"));
    char szSQL[1024] = {0};
    char szID[8] = {0};
    CTextUtility::UnicodeToMB(sText.Left(nPos).GetData(), szID, sizeof(szID));
    sprintf(szSQL, "select nyxm_word.id,nyxm_word.word,nyxm_word.mean,nyxm_word.enSymbol,nyxm_word.usSymbol,nyxm_unit_word.fenjie \
        from nyxm_word, nyxm_unit_word where nyxm_word.id=nyxm_unit_word.wordId and nyxm_unit_word.uid=%s", szID);
    SQLiteStatement* stmt = m_db.Statement(szSQL);
    while (stmt->NextRow())
    {
        TUnitWord tw;
        memset(&tw, 0, sizeof(tw));
        tw.nWordId = stmt->ValueInt(0);
        CTextUtility::MultiToWChars(stmt->ValueString(1).c_str(), tw.szWord, sizeof(tw.szWord));
        CTextUtility::UTF8ToGB(stmt->ValueString(2).c_str(), tw.szWordMeaning, sizeof(tw.szWordMeaning));
        CTextUtility::UTF8ToGB(stmt->ValueString(3).c_str(), tw.szEnSymbol, sizeof(tw.szEnSymbol));
        CTextUtility::UTF8ToGB(stmt->ValueString(4).c_str(), tw.szUsSymbol, sizeof(tw.szUsSymbol));
        CTextUtility::UTF8ToGB(stmt->ValueString(5).c_str(), tw.szFenjie, sizeof(tw.szFenjie));
        sscanf(szID,"%d",&tw.nUnitId);
        tw.bChecked = 0;
        m_vectWords.push_back(tw);
    }

    return m_vectWords.size();
}

int CWPModel::GetWordCountByUnit(LPCTSTR lpUnit)
{
    CDuiString sText = lpUnit;
    int nPos = sText.Find(_T("_"));
    char szSQL[1024] = {0};
    char szID[8] = {0};
    CTextUtility::UnicodeToMB(sText.Left(nPos).GetData(), szID, sizeof(szID));
    sprintf(szSQL, "select count(*) from nyxm_unit_word where uid=%s", szID);
    SQLiteStatement* stmt = m_db.Statement(szSQL);
    if (stmt != NULL)
    {
        stmt->NextRow();
        int nCount = stmt->ValueInt(0);
        return nCount;
    }

    return 0;
}

void CWPModel::SetView(IWPViewModel* pWnd)
{
    m_pViewModel = pWnd;
}


UINT CWPModel::GetTrainMode()
{
    return m_nTrainMode;
}

UINT CWPModel::GetReviewMode()
{
    return m_nReviewMode;
}

void CWPModel::SetReviewMode(int nReviewMode)
{
    m_nReviewMode = nReviewMode;
}

int CWPModel::GetCommonSentencesOfWord(TUnitWord* pUnitWord)
{
    if (NULL == pUnitWord)
    {
        return 0;
    }

    if (pUnitWord->vectSCommons.empty())
    {
        char szSQL[1024] = {0};
        sprintf(szSQL,"select * from nyxm_common_sentence where nyxm_common_sentence.wordId=%d", pUnitWord->nWordId);
        SQLiteStatement* stmt = m_db.Statement(szSQL);
        while (stmt->NextRow())
        {
            TCHAR szType[8] = {0};
            TCHAR szTypeName[16] = {0};
            int nCommonId = 0;
            int nSub = 0;
            nCommonId = stmt->ValueInt(0);
            CTextUtility::MultiToWChars(stmt->ValueString(2).c_str(), szType, sizeof(szType));
            CTextUtility::UTF8ToGB(stmt->ValueString(3).c_str(), szTypeName, sizeof(szTypeName));
            nSub = stmt->ValueInt(4);
            
            if (0 == nSub)
            {
                sprintf(szSQL, "select enSimple, zhSimple from nyxm_common_sentence_item where commonSentenceId=%d limit 3", nCommonId);
                SQLiteStatement* stmtCommon = m_db.Statement(szSQL);
                while (stmtCommon->NextRow())
                {
                    TSCommonItem scItem;
                    memset(&scItem, 0, sizeof(scItem));
                    scItem.nIsSub = 0;
                    _tcscpy_s(scItem.szType, _countof(scItem.szType), szType);
                    _tcscpy_s(scItem.szTypeName, _countof(scItem.szTypeName), szTypeName);
                    CTextUtility::UTF8ToGB(stmtCommon->ValueString(0).c_str(), scItem.szEnCommonSentence, sizeof(scItem.szEnCommonSentence));
                    CTextUtility::UTF8ToGB(stmtCommon->ValueString(1).c_str(), scItem.szZnCommonSentence, sizeof(scItem.szZnCommonSentence));
                    pUnitWord->vectSCommons.push_back(scItem);
                }
            }
            else if (1 == nSub)
            {
                sprintf(szSQL,"SELECT s1.id, s1.useTypeName,s2.content,s3.enSimple,s3.zhSimple,s3.id as sid \
                              FROM nyxm_sub_common_sentence AS s1 \
                              LEFT JOIN nyxm_sub_common_sentence_list AS s2  ON s2.subCommonSentenceId IN (s1.id) \
                              LEFT JOIN nyxm_sub_common_sentence_list_item AS s3 ON s3.subCommonSentenceListId IN (s2.id) \
                              WHERE s1.id IN (select id from nyxm_sub_common_sentence where commonSentenceId=%d) limit 3", nCommonId);
                SQLiteStatement* stmtSubCommon = m_db.Statement(szSQL);
                while (stmtSubCommon->NextRow())
                {
                    TSCommonItem scItem;
                    memset(&scItem, 0, sizeof(scItem));
                    scItem.nIsSub = 1;
                    _tcscpy_s(scItem.szType, _countof(scItem.szType), szType);
                    _tcscpy_s(scItem.szTypeName, _countof(scItem.szTypeName), szTypeName);
                    CTextUtility::UTF8ToGB(stmtSubCommon->ValueString(1).c_str(), scItem.szSubTypeName, sizeof(scItem.szSubTypeName));
                    CTextUtility::UTF8ToGB(stmtSubCommon->ValueString(2).c_str(), scItem.szSubContent, sizeof(scItem.szSubContent));
                    CTextUtility::UTF8ToGB(stmtSubCommon->ValueString(3).c_str(), scItem.szEnCommonSentence, sizeof(scItem.szEnCommonSentence));
                    CTextUtility::UTF8ToGB(stmtSubCommon->ValueString(4).c_str(), scItem.szZnCommonSentence, sizeof(scItem.szZnCommonSentence));
                    
                    pUnitWord->vectSCommons.push_back(scItem);
                }   
            }
        }
    }
}

int CWPModel::GetSimpleSentencesOfWord(TUnitWord* pUnitWord)
{
    if (NULL == pUnitWord)
    {
        return 0;
    }
  
    if (pUnitWord->vectSSents.empty())
    {
        char szSQL[1024] = {0};
        sprintf(szSQL, "select nyxm_simple_sentence.useType, nyxm_simple_sentence.useTypeName, \
                       nyxm_simple_sentence_item.enSimple, nyxm_simple_sentence_item.zhSimple  \
                       from nyxm_simple_sentence, nyxm_simple_sentence_item \
                       where nyxm_simple_sentence.wordId=%d and nyxm_simple_sentence.id=nyxm_simple_sentence_item.simpleSentenceId limit 3", pUnitWord->nWordId);
        SQLiteStatement* stmt = m_db.Statement(szSQL);
        while (stmt->NextRow())
        {
            TSSentItem ssItem;
            memset(&ssItem, 0, sizeof(ssItem));
            CTextUtility::MultiToWChars(stmt->ValueString(0).c_str(), ssItem.szType, sizeof(ssItem.szType));
            CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), ssItem.szTypeName, sizeof(ssItem.szTypeName));
            CTextUtility::UTF8ToGB(stmt->ValueString(2).c_str(), ssItem.szEnSimpleSentence, sizeof(ssItem.szEnSimpleSentence));
            CTextUtility::UTF8ToGB(stmt->ValueString(3).c_str(), ssItem.szZnSimpleSentence, sizeof(ssItem.szZnSimpleSentence));


            pUnitWord->vectSSents.push_back(ssItem);
        }
    }

    return pUnitWord->vectSSents.size();
}

int CWPModel::GetSelectWords(std::vector<TUnitWord *> &selectWords)
{

    selectWords.clear();
    for (int i = 0; i < m_vectWords.size(); ++i)
    {
        if (m_vectWords[i].bChecked)
        {
            selectWords.push_back(&m_vectWords[i]);
        }
    }

    return selectWords.size();
}

int CWPModel::GetWordMeaning(TUnitWord* pUnitWord)
{
    if (NULL == pUnitWord)
    {
        return 0;
    }

    if (pUnitWord->vectWordMeanings.empty())
    {
        char szSQL[1024] = {0};

        sprintf(szSQL,"select useType, meaning from nyxm_word_meaning where nyxm_word_meaning.wordId=%d",pUnitWord->nWordId);
        SQLiteStatement* stmt = m_db.Statement(szSQL);
        while (stmt->NextRow())
        {
            TWordMeaningItem wmItem;
            memset(&wmItem, 0, sizeof(wmItem));
            CTextUtility::MultiToWChars(stmt->ValueString(0).c_str(), wmItem.szType, sizeof(wmItem.szType));
            CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), wmItem.szMeaning, sizeof(wmItem.szMeaning));
            pUnitWord->vectWordMeanings.push_back(wmItem);
        }
    }

    return pUnitWord->vectWordMeanings.size();  
}

int CWPModel::GetWordUsage(TUnitWord* pUnitWord)
{
    if (NULL == pUnitWord)
    {
        return 0;
    }

    if (pUnitWord->vectWordUsage.empty())
    {
        char szSQL[1024] = {0};

        sprintf(szSQL,"select nyxm_word_usage.useType,nyxm_word_usage.useTypeName, nyxm_word_usage_item.content \
                      from nyxm_word_usage, nyxm_word_usage_item \
                      where nyxm_word_usage.wordId=%d and nyxm_word_usage.id = nyxm_word_usage_item.wordUsageId",
                      pUnitWord->nWordId);
        SQLiteStatement* stmt = m_db.Statement(szSQL);
        while (stmt->NextRow())
        {
            TWordUsageItem usageItem;
            memset(&usageItem, 0, sizeof(usageItem));
            CTextUtility::MultiToWChars(stmt->ValueString(0).c_str(), usageItem.szType, sizeof(usageItem.szType));
            CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), usageItem.szTypeName, sizeof(usageItem.szTypeName));
            CTextUtility::UTF8ToGB(stmt->ValueString(2).c_str(), usageItem.szContent, sizeof(usageItem.szContent));
            pUnitWord->vectWordUsage.push_back(usageItem);
        }
    }
    return pUnitWord->vectWordUsage.size();
}

int CWPModel::GetNineWords(TUnitWord* pUnitWord, std::vector<TUnitWord *> &nineWords)
{
    std::vector<TUnitWord *> selectWords;
    GetSelectWords(selectWords);

    std::vector<TUnitWord *> excludeWords;

    if (selectWords.size() >= 9)
    {
        if (nineWords.empty())
        {
            for (int i = 0; i < 9; ++i)
            {
                nineWords.push_back(selectWords[i]);
            }
            return 1;
        }

        nineWords.clear();
        for (int i = 0; i < selectWords.size(); ++i)
        {
            excludeWords.push_back(pUnitWord);
            if (selectWords[i]->nWordId == pUnitWord->nWordId)
            {
                for (int j = i, k = 0; j < selectWords.size() && k < 9; ++j,++k )
                {
                    nineWords.push_back(selectWords[j]);
                }
                break;
            }
        }
    }
    else
    {
        nineWords.clear();
        for (int i = 0; i < selectWords.size(); ++i)
        {
            excludeWords.push_back(pUnitWord);
            if (selectWords[i]->nWordId == pUnitWord->nWordId)
            {
                for (int j = i, k = 0; j < selectWords.size() && k < 9; ++j,++k )
                {
                    nineWords.push_back(selectWords[j]);
                }
                break;
            }
        }
    }

    if (9 == nineWords.size())
    {
        return 1;
    }
    
    int nLimit = 9 - nineWords.size();
    char sWhere[128] = {0};
    for (int i = 0;  i < excludeWords.size(); ++i)
    {
        char sID[32] = {0};
        sprintf(sID, "%d,", excludeWords[i]->nWordId);
        strcat(sWhere, sID);
    }

    for (int i = 0;  i < nineWords.size(); ++i)
    {
        char sID[32] = {0};
        sprintf(sID, "%d,", nineWords[i]->nWordId);
        strcat(sWhere, sID);
    }

    CDuiString strName = CWPContext::getInstance()->GetUnit();
    int nPos = strName.Find(_T("_"));
    char szID[8] = {0};
    CTextUtility::UnicodeToMB(strName.Left(nPos).GetData(), szID, sizeof(szID));
    
    int nCount = 0;
    char szSQL[1024] = {0};
    sprintf(szSQL, "select nyxm_word.id, nyxm_word.mean, nyxm_word.word from nyxm_unit_word, nyxm_word  \
                   where (nyxm_unit_word.wordId=nyxm_word.id) \
                   and (nyxm_unit_word.uid=%s) \
                   and nyxm_unit_word.wordId not in(%s 0) \
                   limit %d", szID, sWhere, nLimit);

    m_vectNineWords.clear();
    SQLiteStatement* stmt = m_db.Statement(szSQL);
    while (stmt->NextRow())
    {
        TUnitWord tw;
        memset(&tw, 0, sizeof(tw));
        tw.nWordId = stmt->ValueInt(0);
        CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), tw.szWordMeaning, sizeof(tw.szWordMeaning));
        CTextUtility::MultiToWChars(stmt->ValueString(2).c_str(), tw.szWord, sizeof(tw.szWord));
        m_vectNineWords.push_back(tw);
        ++nCount;
    }

    if (nCount < nLimit)
    {
        for (int i = 0;  i < m_vectNineWords.size(); ++i)
        {
            char sID[32] = {0};
            sprintf(sID, "%d,", m_vectNineWords[i].nWordId);
            strcat(sWhere, sID);
        }

        sprintf(szSQL, "select nyxm_word.id, nyxm_word.mean, nyxm_word.word from nyxm_unit_word, nyxm_word  \
                       where (nyxm_unit_word.wordId=nyxm_word.id) \
                       and nyxm_unit_word.wordId not in(%s 0) \
                       limit %d", sWhere, nLimit-nCount);

        SQLiteStatement* stmtSub = m_db.Statement(szSQL);
        while (stmtSub->NextRow())
        {
            TUnitWord tw;
            memset(&tw, 0, sizeof(tw));
            tw.nWordId = stmtSub->ValueInt(0);
            CTextUtility::UTF8ToGB(stmtSub->ValueString(1).c_str(), tw.szWordMeaning, sizeof(tw.szWordMeaning));
            CTextUtility::MultiToWChars(stmtSub->ValueString(2).c_str(), tw.szWord, sizeof(tw.szWord));
            m_vectNineWords.push_back(tw);
        }
    }
    
    for (int i = 0;  i < m_vectNineWords.size(); ++i)
    {
        nineWords.push_back(&m_vectNineWords[i]);
    }

    return 0;
}

int CWPModel::GetExerEn2Ch(TExerEn2Ch& exItem)
{
    std::vector<TUnitWord *> nineWords;
    GetNineWords(exItem.pUnitWord, nineWords);
    int nCount = 0;
    srand( (unsigned)time( NULL ) ); 
    exItem.nMode = rand() % 2;
    exItem.nAnswer = rand() % 4;
    int nPos = 0;
    while (nCount < 4)
    {
        if (nCount == exItem.nAnswer)
        {
            GetWordMeaning(exItem.pUnitWord);
            CDuiString sMeaning;
            for (int j = 0; j < exItem.pUnitWord->vectWordMeanings.size(); ++j)
            {
                sMeaning += exItem.pUnitWord->vectWordMeanings[j].szType;
                sMeaning += exItem.pUnitWord->vectWordMeanings[j].szMeaning;
                sMeaning += _T(";  ");
            } 
            exItem.vectExerOptions.push_back(sMeaning);
            exItem.vectChExerOpts.push_back(sMeaning);

            sMeaning = exItem.pUnitWord->szWord;
            exItem.vectEnExerOpts.push_back(sMeaning);

            exItem.vectOptions.push_back(exItem.pUnitWord);
            ++nCount;
        }
        else
        {
            while (1)
            {
                nPos = rand() % nineWords.size();
                BOOL bRepeat = FALSE;
                for ( int j = 0; j < exItem.vectOptions.size(); ++j )
                {
                    if (exItem.vectOptions[j]->nWordId == nineWords[nPos]->nWordId)
                    {
                        bRepeat = TRUE;
                    }
                }

                if (!bRepeat)
                {
                    break;
                }
            }

            if (nineWords[nPos]->nWordId != exItem.pUnitWord->nWordId)
            {
                GetWordMeaning(nineWords[nPos]);
                TUnitWord* pWord = nineWords[nPos];
                CDuiString sMeaning;
                for (int j = 0; j < pWord->vectWordMeanings.size(); ++j)
                {
                    sMeaning += pWord->vectWordMeanings[j].szType;
                    sMeaning += pWord->vectWordMeanings[j].szMeaning;
                    sMeaning += _T(";  ");
                }  

                exItem.vectExerOptions.push_back(sMeaning);
                exItem.vectChExerOpts.push_back(sMeaning);

                sMeaning = pWord->szWord;
                exItem.vectEnExerOpts.push_back(sMeaning);

                exItem.vectOptions.push_back(pWord);
                ++nCount;
            }
        }
        
    }
    
    return 0;
}

int CWPModel::GetUnitInfo(int nUnitId, CDuiString &strUnit, CDuiString &strSems, CDuiString &strVer)
{
    char szSQL[1024] = {0};
    sprintf(szSQL, "select nyxm_unit.name, nyxm_semester.name, nyxm_version.name \
                   from nyxm_unit, nyxm_semester, nyxm_version \
                   where nyxm_unit.id==%d and nyxm_unit.sid = nyxm_semester.id and nyxm_semester.vid == nyxm_version.id", nUnitId);
    SQLiteStatement* stmt = m_db.Statement(szSQL);
    TCHAR szValue[256] = {0};
    while (stmt->NextRow())
    {
        CTextUtility::UTF8ToGB(stmt->ValueString(0).c_str(), szValue, sizeof(szValue));
        strUnit = szValue;

        CTextUtility::UTF8ToGB(stmt->ValueString(1).c_str(), szValue, sizeof(szValue));
        strSems = szValue;

        CTextUtility::UTF8ToGB(stmt->ValueString(2).c_str(), szValue, sizeof(szValue));
        strVer = szValue;
    }

    return 0;
}

int CWPModel::GetNewWords()
{
    m_vectWords.clear();
    char szSQL[1024] = {0};
    sprintf(szSQL, "select nyxm_word.id,nyxm_word.word,nyxm_word.mean,nyxm_word.enSymbol,nyxm_word.usSymbol, nyxm_new_word.unitId \
                   from nyxm_word, nyxm_new_word where nyxm_word.id=nyxm_new_word.wordId %s", "");

    SQLiteStatement* stmtNWS = m_db.Statement(szSQL);
    while (stmtNWS->NextRow())
    {
        TUnitWord tw;
        memset(&tw, 0, sizeof(tw));
        tw.nWordId = stmtNWS->ValueInt(0);
        CTextUtility::MultiToWChars(stmtNWS->ValueString(1).c_str(), tw.szWord, sizeof(tw.szWord));
        CTextUtility::UTF8ToGB(stmtNWS->ValueString(2).c_str(), tw.szWordMeaning, sizeof(tw.szWordMeaning));
        CTextUtility::UTF8ToGB(stmtNWS->ValueString(3).c_str(), tw.szEnSymbol, sizeof(tw.szEnSymbol));
        CTextUtility::UTF8ToGB(stmtNWS->ValueString(4).c_str(), tw.szUsSymbol, sizeof(tw.szUsSymbol));
        CTextUtility::UTF8ToGB(stmtNWS->ValueString(1).c_str(), tw.szFenjie, sizeof(tw.szFenjie));
        tw.nUnitId = stmtNWS->ValueInt(5);
        tw.bChecked = 0;
        m_vectWords.push_back(tw);
    }

    int nCount = m_vectWords.size();

    return nCount;
}

int CWPModel::AddNewWord(TUnitWord* pUnitWord)
{
    char szSQL[1024] = {0};
    sprintf(szSQL, "select count(*) from nyxm_new_word where wordId == %d ", pUnitWord->nWordId);
    SQLiteStatement* stmtNW = m_db.Statement(szSQL);
    int nTag = 0;
    if (stmtNW->NextRow())
    {
        nTag = stmtNW->ValueInt(0);
    }

    if (nTag >= 1)
    {
        return 0;
    }

    CDuiString strVersionId = CWPContext::getInstance()->GetTeachingMaterial();
    int nPosVer = strVersionId.Find(_T("_"));
    char szVerId[8] = {0};
    CTextUtility::UnicodeToMB(strVersionId.Left(nPosVer).GetData(), szVerId, sizeof(szVerId));

    CDuiString strSemesterId = CWPContext::getInstance()->GetGrade();
    int nPosSem = strSemesterId.Find(_T("_"));
    char szSemId[8] = {0};
    CTextUtility::UnicodeToMB(strSemesterId.Left(nPosSem).GetData(), szSemId, sizeof(szSemId));

    CDuiString strUnitId = CWPContext::getInstance()->GetUnit();
    int nPosUnit = strUnitId.Find(_T("_"));
    char szUnitId[8] = {0};
    CTextUtility::UnicodeToMB(strUnitId.Left(nPosUnit).GetData(), szUnitId, sizeof(szUnitId));

    struct tm *newtime;
    char tmpbuf[128] = {0};
    time_t lt1;
    time( &lt1 );
    newtime = localtime(&lt1);
    strftime( tmpbuf, 128, "%Y-%m-%d", newtime);

    sprintf(szSQL, "INSERT INTO nyxm_new_word (unitId, wordId, date, num, userId) \
                   VALUES (%d, %d, '%s', 0, 1000)", 
                   pUnitWord->nUnitId, pUnitWord->nWordId, tmpbuf);

    bool bRet = m_db.DirectStatement(szSQL);

    string strLast = m_db.LastError();

    return bRet;
}

int CWPModel::DeleteNewWord(TUnitWord* pUnitWord)
{
    char szSQL[1024] = {0};

    CDuiString strVersionId = CWPContext::getInstance()->GetTeachingMaterial();
    int nPosVer = strVersionId.Find(_T("_"));
    char szVerId[8] = {0};
    CTextUtility::UnicodeToMB(strVersionId.Left(nPosVer).GetData(), szVerId, sizeof(szVerId));

    CDuiString strSemesterId = CWPContext::getInstance()->GetGrade();
    int nPosSem = strSemesterId.Find(_T("_"));
    char szSemId[8] = {0};
    CTextUtility::UnicodeToMB(strSemesterId.Left(nPosSem).GetData(), szSemId, sizeof(szSemId));

    CDuiString strUnitId = CWPContext::getInstance()->GetUnit();
    int nPosUnit = strUnitId.Find(_T("_"));
    char szUnitId[8] = {0};
    CTextUtility::UnicodeToMB(strUnitId.Left(nPosUnit).GetData(), szUnitId, sizeof(szUnitId));

    sprintf(szSQL, "DELETE FROM nyxm_new_word WHERE wordId==%d", pUnitWord->nWordId);

    bool bRet = m_db.DirectStatement(szSQL);

    string strLast = m_db.LastError();

    return bRet;
}

int CWPModel::GetStudyRecordsEx()
{
    m_vectStudyRecords.clear();

    char szSQL[1024] = {0};
    sprintf(szSQL, "select study_time, sum(spend_time) from nyxm_word_study_record group by study_time order by study_time desc");
    SQLiteStatement* stmt = m_db.Statement(szSQL);
    while (stmt->NextRow())
    {
        TStudyRecord srItem;
        memset(&srItem, 0, sizeof(srItem));
        srItem.nSpendTime = stmt->ValueInt(1);
        CTextUtility::MultiToWChars(stmt->ValueString(0).c_str(), srItem.szStudyTime, sizeof(srItem.szStudyTime));
        m_vectStudyRecords.push_back(srItem);
    }

    for (int i = 0; i < m_vectStudyRecords.size(); ++i)
    {
        char szValue[32] = {0};
        CTextUtility::UnicodeToMB(m_vectStudyRecords[i].szStudyTime, szValue, sizeof(szValue));
        sprintf(szSQL, "select unit_id, total_word, new_word from nyxm_word_study_record where study_time==\"%s\" ", szValue);
        SQLiteStatement* stmtRecs = m_db.Statement(szSQL);
        string strTotalWords, strNewWords;
        while (stmtRecs->NextRow())
        {
            int nUnitId = stmtRecs->ValueInt(0);
            strTotalWords = stmtRecs->ValueString(1);
            strNewWords = stmtRecs->ValueString(2);

            sprintf(szSQL, "select nyxm_word.id,nyxm_word.word,nyxm_word.mean,nyxm_word.enSymbol,nyxm_word.usSymbol \
                           from nyxm_word where nyxm_word.id in (%s)",strTotalWords.c_str());
            SQLiteStatement* stmtWord = m_db.Statement(szSQL);
            while (stmtWord->NextRow())
            {
                TUnitWord tw;
                memset(&tw, 0, sizeof(tw));
                tw.nWordId = stmtWord->ValueInt(0);
                CTextUtility::MultiToWChars(stmtWord->ValueString(1).c_str(), tw.szWord, sizeof(tw.szWord));
                CTextUtility::UTF8ToGB(stmtWord->ValueString(2).c_str(), tw.szWordMeaning, sizeof(tw.szWordMeaning));
                CTextUtility::UTF8ToGB(stmtWord->ValueString(3).c_str(), tw.szEnSymbol, sizeof(tw.szEnSymbol));
                CTextUtility::UTF8ToGB(stmtWord->ValueString(4).c_str(), tw.szUsSymbol, sizeof(tw.szUsSymbol));
                CTextUtility::UTF8ToGB(stmtWord->ValueString(1).c_str(), tw.szFenjie, sizeof(tw.szFenjie));
                tw.nUnitId = nUnitId;
                tw.bChecked = 0;
                m_vectStudyRecords[i].vectTotalWords.push_back(tw);
            }


            sprintf(szSQL, "select nyxm_word.id,nyxm_word.word,nyxm_word.mean,nyxm_word.enSymbol,nyxm_word.usSymbol \
                           from nyxm_word where nyxm_word.id in (%s)", strNewWords.c_str());
            SQLiteStatement* stmtNewWord = m_db.Statement(szSQL);
            while (stmtNewWord->NextRow())
            {
                TUnitWord tw;
                memset(&tw, 0, sizeof(tw));
                tw.nWordId = stmtWord->ValueInt(0);
                CTextUtility::MultiToWChars(stmtNewWord->ValueString(1).c_str(), tw.szWord, sizeof(tw.szWord));
                CTextUtility::UTF8ToGB(stmtNewWord->ValueString(2).c_str(), tw.szWordMeaning, sizeof(tw.szWordMeaning));
                CTextUtility::UTF8ToGB(stmtNewWord->ValueString(3).c_str(), tw.szEnSymbol, sizeof(tw.szEnSymbol));
                CTextUtility::UTF8ToGB(stmtNewWord->ValueString(4).c_str(), tw.szUsSymbol, sizeof(tw.szUsSymbol));
                CTextUtility::UTF8ToGB(stmtNewWord->ValueString(1).c_str(), tw.szFenjie, sizeof(tw.szFenjie));
                tw.bChecked = 0;
                tw.nUnitId = nUnitId;
                m_vectStudyRecords[i].vectNewWords.push_back(tw);
            }
        }

    }
}

int CWPModel::GetStudyRecords()
{
    int nCount = 0;

    char szSQL[1024] = {0};
    char szDate[32] = {0};

    sprintf(szSQL, "select * from nyxm_word_study_record order by study_time desc");

    m_vectStudyRecords.clear();

    SQLiteStatement* stmtSR = m_db.Statement(szSQL);
    while (stmtSR->NextRow())
    {
        TStudyRecord srItem;
        memset(&srItem, 0, sizeof(srItem));
        srItem.nSpendTime = stmtSR->ValueInt(7);

        int nUnitID = stmtSR->ValueInt(4);
        int nSemID = stmtSR->ValueInt(3);
        int nVerID = stmtSR->ValueInt(2);


        string strTotal = stmtSR->ValueString(5);
        sprintf(szSQL, "select nyxm_word.id,nyxm_word.word,nyxm_word.mean,nyxm_word.enSymbol,nyxm_word.usSymbol \
                       from nyxm_word where nyxm_word.id in (%s)",strTotal.c_str());
        SQLiteStatement* stmtWord = m_db.Statement(szSQL);
        while (stmtWord->NextRow())
        {
            TUnitWord tw;
            memset(&tw, 0, sizeof(tw));
            tw.nWordId = stmtWord->ValueInt(0);
            CTextUtility::MultiToWChars(stmtWord->ValueString(1).c_str(), tw.szWord, sizeof(tw.szWord));
            CTextUtility::UTF8ToGB(stmtWord->ValueString(2).c_str(), tw.szWordMeaning, sizeof(tw.szWordMeaning));
            CTextUtility::UTF8ToGB(stmtWord->ValueString(3).c_str(), tw.szEnSymbol, sizeof(tw.szEnSymbol));
            CTextUtility::UTF8ToGB(stmtWord->ValueString(4).c_str(), tw.szUsSymbol, sizeof(tw.szUsSymbol));
            CTextUtility::UTF8ToGB(stmtWord->ValueString(1).c_str(), tw.szFenjie, sizeof(tw.szFenjie));
            tw.nUnitId = nUnitID;
            tw.bChecked = 0;
            srItem.vectTotalWords.push_back(tw);
        }

        string strNewWords = stmtSR->ValueString(6);
        sprintf(szSQL, "select nyxm_word.id,nyxm_word.word,nyxm_word.mean,nyxm_word.enSymbol,nyxm_word.usSymbol \
                       from nyxm_word where nyxm_word.id in (%s)", strNewWords.c_str());
        SQLiteStatement* stmtNewWord = m_db.Statement(szSQL);
        while (stmtNewWord->NextRow())
        {
            TUnitWord tw;
            memset(&tw, 0, sizeof(tw));
            tw.nWordId = stmtWord->ValueInt(0);
            CTextUtility::MultiToWChars(stmtNewWord->ValueString(1).c_str(), tw.szWord, sizeof(tw.szWord));
            CTextUtility::UTF8ToGB(stmtNewWord->ValueString(2).c_str(), tw.szWordMeaning, sizeof(tw.szWordMeaning));
            CTextUtility::UTF8ToGB(stmtNewWord->ValueString(3).c_str(), tw.szEnSymbol, sizeof(tw.szEnSymbol));
            CTextUtility::UTF8ToGB(stmtNewWord->ValueString(4).c_str(), tw.szUsSymbol, sizeof(tw.szUsSymbol));
            CTextUtility::UTF8ToGB(stmtNewWord->ValueString(1).c_str(), tw.szFenjie, sizeof(tw.szFenjie));
            tw.bChecked = 0;
            tw.nUnitId = nUnitID;
            srItem.vectNewWords.push_back(tw);
        }

        //string strDesc;
        //sprintf(szSQL,"select name from nyxm_version where id=%d", nVerID);
        //SQLiteStatement* stmtVers = m_db.Statement(szSQL);
        //if (stmtVers)
        //{
        //    stmtVers->NextRow();
        //    strDesc = stmtVers->ValueString(0) + "-";
        //}

        //sprintf(szSQL,"select name from nyxm_semester where id=%d", nSemID);
        //SQLiteStatement* stmtSeme = m_db.Statement(szSQL);
        //if (stmtSeme)
        //{
        //    stmtSeme->NextRow();
        //    strDesc += stmtSeme->ValueString(0) + "-";
        //}

        //sprintf(szSQL,"select name from nyxm_unit where id=%d", nUnitID);
        //SQLiteStatement* stmtUnit = m_db.Statement(szSQL);
        //if (stmtUnit)
        //{
        //    stmtUnit->NextRow();
        //    strDesc += stmtUnit->ValueString(0);
        //}

        //CTextUtility::MultiToWChars(strDesc.c_str(), srItem.szUnitDesc, sizeof(srItem.szUnitDesc));
        
        CTextUtility::MultiToWChars(stmtSR->ValueString(8).c_str(), srItem.szStudyTime, sizeof(srItem.szStudyTime));

        m_vectStudyRecords.push_back(srItem);
    }

    nCount = m_vectStudyRecords.size();

    return nCount;
}

int CWPModel::AddStudyRecords(TExerEn2Ch& exItem)
{
    struct tm *newtime;
    char szDate[32] = {0};
    time_t lt1;
    time( &lt1 );
    newtime = localtime(&lt1);
    strftime( szDate, 32, "%Y-%m-%d", newtime);
    char szSQL[1024] = {0};
    sprintf(szSQL, "select total_word,new_word,spend_time from nyxm_word_study_record where study_time == \"%s\" ", szDate);
    SQLiteStatement* stmt = m_db.Statement(szSQL);
    int nSpendTime = 0;
    int nTag = 0;
    string strTotalWord, strNewWord;
    if (stmt)
    {
        if (stmt->NextRow())
        {
            strTotalWord = stmt->ValueString(0);
            strNewWord = stmt->ValueString(1);
            nSpendTime = stmt->ValueInt(2);
            nTag = 1;
        }
    }

    if (0 == nTag)
    {
        if (exItem.nIsAnswerRight)
        {
            sprintf(szSQL, "INSERT INTO nyxm_word_study_record (unit_id, study_time, spend_time, total_word) \
                           VALUES (%d, \"%s\", %d, \"%d\")", exItem.pUnitWord->nUnitId,
                           szDate, exItem.nSpendTime, exItem.pUnitWord->nWordId);
        }
        else
        {
            sprintf(szSQL, "INSERT INTO nyxm_word_study_record (unit_id, study_time, spend_time, total_word, new_word) \
                           VALUES (%d, \"%s\", %d, \"%d\", \"%d\")", exItem.pUnitWord->nUnitId,
                           szDate, exItem.nSpendTime, exItem.pUnitWord->nWordId, exItem.pUnitWord->nWordId);
        }    
    }
    else
    {
        char szWordId[16] = {0};
        sprintf(szWordId, "%d", exItem.pUnitWord->nWordId);
        if (-1 == strTotalWord.find(szWordId))
        {
            strTotalWord.append(",");
            strTotalWord.append(szWordId);
        }

        if (-1 == strNewWord.find(szWordId))
        {
            strNewWord.append(",");
            strNewWord.append(szWordId);
        }

        if (exItem.nIsAnswerRight)
        {
            sprintf(szSQL, "UPDATE nyxm_word_study_record SET spend_time=%d, total_word=\"%s\" \
                           WHERE study_time=\"%s\" ",
                           exItem.nSpendTime+nSpendTime, strTotalWord.c_str(), szDate);
        }
        else
        {
            sprintf(szSQL, "UPDATE nyxm_word_study_record SET spend_time=%d, total_word=\"%s\", new_word=\"%s\" \
                           WHERE study_time=\"%s\" ",
                           exItem.nSpendTime+nSpendTime, strTotalWord.c_str(), strNewWord.c_str(), szDate);
        }
        
    }

    bool bRet = m_db.DirectStatement(szSQL);

    string strLast = m_db.LastError();

    return bRet;
}